#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <mqueue.h>
#include <time.h>

int main(void){
  // 设置消息队列参数
  struct mq_attr my_mq_atrr;
  my_mq_atrr.mq_curmsgs=0; //当前消息数量
  my_mq_atrr.mq_flags=0; // 消息状态，默认为0
  my_mq_atrr.mq_maxmsg=10; //消息队列容量
  my_mq_atrr.mq_msgsize=100; // 每条消息的大小-字节

  // 设置消息队列名称
  char *mq_name = "/father_son_mq";
  // 创建消息队列
  mqd_t mqd = mq_open(mq_name,O_CREAT|O_RDWR,0644,&my_mq_atrr);
  if(mqd==-1){
    perror("mq_open");
    exit(EXIT_FAILURE);
  }
  pid_t son_pid = fork();
  if(son_pid==-1){
    perror("fork");
    exit(EXIT_FAILURE);
  }
  if(son_pid==0){ // 子进程接收
    char recieve_buf[100]={0};
    struct timespec time_info;
    for(int i=0;i<10;i++){
      // 先清空缓冲区旧数据
      memset(recieve_buf,0,100);
      // 准备超时时间
      clock_gettime(0,&time_info);
      time_info.tv_sec+=15;//设置15秒超时
      if(mq_timedreceive(mqd,recieve_buf,100,0,&time_info)==-1){
        perror("mq_timedreceive");
      }else{
        printf("子进程接收到了一条消息:%s\n",recieve_buf);
      }
    }
  }else{ // 父进程发送
    char send_buf[100]={0};
    struct timespec time_info;
    for(int i=0;i<10;i++){
      // 先清空缓冲区旧数据
      memset(send_buf,0,100);
      sprintf(send_buf,"父进程%d第%d次发送数据:hello",
        getpid(),(i+1));
      // 准备超时时间
      clock_gettime(0,&time_info);
      time_info.tv_sec+=5;//设置5秒超时
      if(mq_timedsend(mqd,send_buf,100,0,&time_info)==-1){
        perror("mq_timedsend");
      }else{
        printf("父进程发送了一条消息\n");
      }
      sleep(1); // 等待子进程获取消息
    }
  }
  close(mqd); // 父子进程最后都要关闭消息队列
  if(son_pid>0){
    mq_unlink(mq_name); // 由父进程清除消息队列
  }
  return 0;
}
